home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / STEP14.PAK / STEP14DV.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  20KB  |  810 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1994 by Borland International
  3. //   Tutorial application
  4. //   OLE 2 container example
  5. //----------------------------------------------------------------------------
  6. #include <owl/pch.h>
  7. #include <owl/dc.h>
  8. #include <owl/inputdia.h>
  9. #include <owl/chooseco.h>
  10. #include <owl/gdiobjec.h>
  11. #include <owl/docmanag.h>
  12. #include <owl/listbox.h>
  13. #include <classlib/arrays.h>
  14. #include <owl/oledoc.h>
  15. #include <owl/oleview.h>
  16. #include <owl/edit.rh>
  17. #include "step14dv.rc"
  18.  
  19. typedef TArray<TPoint> TPoints;
  20. typedef TArrayIterator<TPoint> TPointsIterator;
  21.  
  22.  
  23. //===============================  TLine  =====================================
  24. //
  25. class TLine : public TPoints {
  26.   public:
  27.     // Constructor to allow construction from a color and a pen size.
  28.     // Also serves as default constructor.
  29.     TLine(const TColor& color = TColor(0), int penSize = 1) :
  30.       TPoints(10, 0, 10), PenSize(penSize), Color(color){}
  31.  
  32.     // Functions to modify and query pen attributes.
  33.     int QueryPenSize() const {return PenSize;}
  34.     const TColor& QueryColor() const {return Color;}
  35.     void SetPen(const TColor& newColor, int penSize = 0);
  36.     void SetPen(int penSize);
  37.     bool GetPenSize();
  38.     bool GetPenColor();
  39.  
  40.     // TLine draws itself.  Returns true if everything went OK.
  41.     virtual bool Draw(TDC&) const;
  42.  
  43.     // The == operator must be defined for the container class, even if unused
  44.     bool operator ==(const TLine& other) const {return &other == this;}
  45.     friend ostream& operator <<(ostream& os, const TLine& line);
  46.     friend istream& operator >>(istream& is, TLine& line);
  47.  
  48.   protected:
  49.     int PenSize;
  50.     TColor Color;
  51. };
  52.  
  53. typedef TArray<TLine> TLines;
  54. typedef TArrayIterator<TLine> TLinesIterator;
  55.  
  56. class _USERCLASS TDrawDocument : public TOleDocument {
  57.   public:
  58.     enum {
  59.       PrevProperty = TOleDocument::NextProperty-1,
  60.       LineCount,
  61.       Description,
  62.       NextProperty,
  63.     };
  64.  
  65.     enum {
  66.       UndoNone,
  67.       UndoDelete,
  68.       UndoAppend,
  69.       UndoModify
  70.     };
  71.  
  72.     TDrawDocument(TDocument* parent = 0);
  73.    ~TDrawDocument() { delete Lines; delete UndoLine; }
  74.  
  75.     // implement virtual methods of TDocument
  76.     bool   Open(int mode, const char far* path=0);
  77.     bool   Close();
  78.     bool   Commit(bool force = false);
  79.  
  80.     int         FindProperty(const char far* name);  // return index
  81.     int         PropertyFlags(int index);
  82.     const char* PropertyName(int index);
  83.     int         PropertyCount() {return NextProperty - 1;}
  84.     int         GetProperty(int index, void far* dest, int textlen=0);
  85.  
  86.     // data access functions
  87.     TLine* GetLine(uint index);
  88.     int    AddLine(TLine& line);
  89.     void   DeleteLine(uint index);
  90.     void   ModifyLine(TLine& line, uint index);
  91.     void   Clear();
  92.     void   Undo();
  93.  
  94.   protected:
  95.     TLines* Lines;
  96.     TLine*  UndoLine;
  97.     int     UndoState;
  98.     int     UndoIndex;
  99.     string  FileInfo;
  100. };
  101.  
  102. class _USERCLASS TDrawView : public TOleView {
  103.   public:
  104.     TDrawView(TDrawDocument& doc, TWindow* parent = 0);
  105.    ~TDrawView() {delete Line;}
  106.     static const char far* StaticName() {return "Draw View";}
  107.     const char far* GetViewName() {return StaticName();}
  108.  
  109.   protected:
  110.     TDrawDocument*    DrawDoc;  // same as Doc member, but cast to derived class
  111.     TPen*             Pen;
  112.     TLine*            Line;     // To hold a single line sent or received from document
  113.  
  114.     // Message response functions
  115.     void EvLButtonDown(uint, TPoint&);
  116.     void EvMouseMove(uint, TPoint&);
  117.     void EvLButtonUp(uint, TPoint&);
  118.  
  119.     void Paint(TDC&, bool, TRect&);
  120.     void CmPenSize();
  121.     void CmPenColor();
  122.     void CmClear();
  123.     void CmUndo();
  124.  
  125.     // Document notifications
  126.     bool VnCommit(bool force);
  127.     bool VnRevert(bool clear);
  128.     bool VnAppend(uint index);
  129.     bool VnDelete(uint index);
  130.     bool VnModify(uint index);
  131.  
  132.   DECLARE_RESPONSE_TABLE(TDrawView);
  133. };
  134.  
  135.  
  136. class _USERCLASS TDrawListView : public TListBox, public TView {
  137.   public:
  138.     TDrawListView(TDrawDocument& doc, TWindow* parent = 0);
  139.    ~TDrawListView(){}
  140.     static const char far* StaticName() {return "DrawList View";}
  141.     int CurIndex;
  142.  
  143.     // Overridden virtuals from TView
  144.     //
  145.     const char far* GetViewName() {return StaticName();}
  146.     TWindow* GetWindow() {return (TWindow*)this;}
  147.     bool SetDocTitle(const char far* docname, int index)
  148.                     {return TListBox::SetDocTitle(docname, index);}
  149.  
  150.     // Overridden virtuals from TWindow
  151.     //
  152.     bool CanClose();
  153.     bool Create();
  154.  
  155.   protected:
  156.     TDrawDocument* DrawDoc;  // same as Doc member, but cast to derived class
  157.     void LoadData();
  158.     void FormatData(const TLine* line, uint index);
  159.  
  160.     // Message response functions
  161.     void CmPenSize();
  162.     void CmPenColor();
  163.     void CmClear();
  164.     void CmUndo();
  165.     void CmDelete();
  166.  
  167.     // Document notifications
  168.     bool VnIsWindow(HWND hWnd) {return HWindow == hWnd;}
  169.     bool VnCommit(bool force);
  170.     bool VnRevert(bool clear);
  171.     bool VnAppend(uint index);
  172.     bool VnDelete(uint index);
  173.     bool VnModify(uint index);
  174.  
  175.   DECLARE_RESPONSE_TABLE(TDrawListView);
  176. };
  177.  
  178. const int vnDrawAppend     = vnCustomBase+0;
  179. const int vnDrawDelete     = vnCustomBase+1;
  180. const int vnDrawModify     = vnCustomBase+2;
  181.  
  182. NOTIFY_SIG(vnDrawAppend, uint)
  183. NOTIFY_SIG(vnDrawDelete, uint)
  184. NOTIFY_SIG(vnDrawModify, uint)
  185.  
  186. #define EV_VN_DRAWAPPEND  VN_DEFINE(vnDrawAppend,  VnAppend,  int)
  187. #define EV_VN_DRAWDELETE  VN_DEFINE(vnDrawDelete,  VnDelete,  int)
  188. #define EV_VN_DRAWMODIFY  VN_DEFINE(vnDrawModify,  VnModify,  int)
  189.  
  190.  
  191. // Register document template info and clipboard formats
  192. //
  193. BEGIN_REGISTRATION(DocReg)
  194.   REGDATA(progid,     "DrawPad.Document.14")
  195.   REGDATA(description,"Drawing Pad (Step14--Container)")
  196.   REGDATA(extension,  "p14")
  197.   REGDATA(docfilter,  "*.p14")
  198.   REGDOCFLAGS(dtAutoOpen | dtAutoDelete | dtUpdateDir | dtCreatePrompt | dtRegisterExt)
  199.   REGFORMAT(0, ocrEmbedSource,  ocrContent,  ocrIStorage, ocrGet)
  200.   REGFORMAT(1, ocrMetafilePict, ocrContent,  ocrMfPict|ocrStaticMed, ocrGet)
  201.   REGFORMAT(2, ocrBitmap, ocrContent,  ocrGDI|ocrStaticMed, ocrGet)
  202.   REGFORMAT(3, ocrDib, ocrContent,  ocrHGlobal|ocrStaticMed, ocrGet)
  203. END_REGISTRATION
  204. BEGIN_REGISTRATION(ListReg)
  205.   REGDATA(description,"Line List")
  206.   REGDATA(extension,  "p14")
  207.   REGDATA(docfilter,  "*.p14")
  208.   REGDOCFLAGS(dtAutoDelete | dtHidden)
  209. END_REGISTRATION
  210.  
  211. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawView,       DrawTemplate);
  212. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawListView,   DrawListTemplate);
  213. DrawTemplate drawTpl(DocReg);
  214. DrawListTemplate drawListTpl(ListReg);
  215.  
  216. //===============================  TLine  =====================================
  217. //
  218. void TLine::SetPen(int penSize)
  219. {
  220.   if (penSize < 1)
  221.     PenSize = 1;
  222.   else
  223.     PenSize = penSize;
  224. }
  225.  
  226. void TLine::SetPen(const TColor &newColor, int penSize)
  227. {
  228.   // If penSize isn't the default (0), set PenSize to the new size.
  229.   if (penSize)
  230.     PenSize = penSize;
  231.  
  232.   Color = newColor;
  233. }
  234.  
  235. bool TLine::Draw(TDC &dc) const
  236. {
  237.   // Set pen for the dc to the values for this line
  238.   TPen pen(Color, PenSize);
  239.   dc.SelectObject(pen);
  240.  
  241.   // Iterates through the points in the line i.
  242.   TPointsIterator j(*this);
  243.   bool first = true;
  244.  
  245.   while (j) {
  246.     TPoint p = j++;
  247.  
  248.     if (!first)
  249.       dc.LineTo(p);
  250.     else {
  251.       dc.MoveTo(p);
  252.       first = false;
  253.     }
  254.   }
  255.   dc.RestorePen();
  256.   return true;
  257. }
  258.  
  259. ostream& operator <<(ostream& os, const TLine& line)
  260. {
  261.   // Write the number of points in the line
  262.   os << line.GetItemsInContainer();
  263.  
  264.   // Get and write pen attributes.
  265.   os << ' ' << line.Color << ' ' << line.PenSize;
  266.  
  267.   // Get an iterator for the array of points
  268.   TPointsIterator j(line);
  269.  
  270.   // While the iterator is valid (i.e. we haven't run out of points)
  271.   while(j)
  272.     // Write the point from the iterator and increment the array.
  273.     os << j++;
  274.   os << '\n';
  275.  
  276.   // return the stream object
  277.   return os;
  278. }
  279.  
  280. istream& operator >>(istream& is, TLine& line)
  281. {
  282.   unsigned numPoints;
  283.   is >> numPoints;
  284.  
  285.   COLORREF color;
  286.   int penSize;
  287.   is >> color >> penSize;
  288.   line.SetPen(TColor(color), penSize);
  289.  
  290.   while (numPoints--) {
  291.     TPoint point;
  292.     is >> point;
  293.     line.Add(point);
  294.   }
  295.  
  296.   // return the stream object
  297.   return is;
  298. }
  299.  
  300. TDrawDocument::TDrawDocument(TDocument* parent)
  301.         : TOleDocument(parent), UndoLine(0),
  302.           UndoState(UndoNone)
  303. {
  304.   Lines = new TLines(100, 0, 5);
  305. }
  306.  
  307. bool TDrawDocument::Commit(bool force)
  308. {
  309.   TOleDocument::Commit(force);
  310.  
  311.   TOutStream* os = OutStream(ofWrite);
  312.   if (!os)
  313.    return false;
  314.  
  315.   // Write the number of lines in the figure
  316.   *os << Lines->GetItemsInContainer();
  317.  
  318.   // Append a description using a resource string
  319.   *os << ' ' << FileInfo << '\n';
  320.  
  321.   // Get an iterator for the array of lines
  322.   TLinesIterator i(*Lines);
  323.  
  324.   // While the iterator is valid (i.e. we haven't run out of lines)
  325.   while (i) {
  326.     // Copy the current line from the iterator and increment the array.
  327.     *os << i++;
  328.   }
  329.  
  330.   delete os;
  331.  
  332.   //
  333.   // Commit the storage if it was opened in transacted mode
  334.   TOleDocument::CommitTransactedStorage();
  335.   SetDirty(false);
  336.   return true;
  337. }
  338.  
  339. bool TDrawDocument::Open(int mode, const char far* path)
  340. {
  341.   char fileinfo[100];
  342.  
  343.   TOleDocument::Open(mode, path);
  344.   if (GetDocPath()) {
  345.     TInStream* is = (TInStream*)InStream(ofRead);
  346.     if (!is)
  347.       return false;
  348.  
  349.     unsigned numLines;
  350.     *is >> numLines;
  351.     is->getline(fileinfo, sizeof(fileinfo));
  352.     while (numLines--) {
  353.       TLine line;
  354.       *is >> line;
  355.       Lines->Add(line);
  356.     }
  357.  
  358.     delete is;
  359.  
  360.     FileInfo = fileinfo;
  361.   } else {
  362.     FileInfo = string(*::Module,IDS_FILEINFO);
  363.   }
  364.   SetDirty(false);
  365.   UndoState = UndoNone;
  366.   return true;
  367. }
  368.  
  369. bool TDrawDocument::Close()
  370. {
  371.   if (TOleDocument::Close()) {
  372.     Lines->Flush();
  373.     return true;
  374.   }
  375.  
  376.   return false;
  377. }
  378.  
  379. TLine* TDrawDocument::GetLine(uint index)
  380. {
  381.   return index < Lines->GetItemsInContainer() ? &(*Lines)[index] : 0;
  382. }
  383.  
  384. int TDrawDocument::AddLine(TLine& line)
  385. {
  386.   int index = Lines->GetItemsInContainer();
  387.   Lines->Add(line);
  388.   SetDirty(true);
  389.   NotifyViews(vnDrawAppend, index);
  390.   UndoState = UndoAppend;
  391.   return index;
  392. }
  393.  
  394. void TDrawDocument::DeleteLine(uint index)
  395. {
  396.   const TLine* oldLine = GetLine(index);
  397.   if (!oldLine)
  398.     return;
  399.   delete UndoLine;
  400.   UndoLine = new TLine(*oldLine);
  401.   Lines->Detach(index);
  402.   SetDirty(true);
  403.   NotifyViews(vnDrawDelete, index);
  404.   UndoState = UndoDelete;
  405. }
  406.  
  407. void TDrawDocument::ModifyLine(TLine& line, uint index)
  408. {
  409.   delete UndoLine;
  410.   UndoLine = new TLine((*Lines)[index]);
  411.   SetDirty(true);
  412.   (*Lines)[index] = line;
  413.   NotifyViews(vnDrawModify, index);
  414.   UndoState = UndoModify;
  415.   UndoIndex = index;
  416. }
  417.  
  418. void TDrawDocument::Clear()
  419. {
  420.   Lines->Flush();
  421.   NotifyViews(vnRevert, true);
  422. }
  423.  
  424. void TDrawDocument::Undo()
  425. {
  426.   switch (UndoState) {
  427.     case UndoAppend:
  428.       DeleteLine(Lines->GetItemsInContainer()-1);
  429.       return;
  430.     case UndoDelete:
  431.       AddLine(*UndoLine);
  432.       delete UndoLine;
  433.       UndoLine = 0;
  434.       return;
  435.     case UndoModify:
  436.       TLine* temp = UndoLine;
  437.       UndoLine = 0;
  438.       ModifyLine(*temp, UndoIndex);
  439.       delete temp;
  440.   }
  441. }
  442.  
  443. bool TLine::GetPenSize()
  444. {
  445.   char inputText[6];
  446.  
  447.   wsprintf(inputText, "%d", PenSize);
  448.   if (TInputDialog(0, "Line Thickness",
  449.                         "Input a new thickness:",
  450.                         inputText,
  451.                         sizeof(inputText),::Module).Execute() != IDOK)
  452.     return false;
  453.   PenSize = atoi(inputText);
  454.  
  455.   if (PenSize < 1)
  456.     PenSize = 1;
  457.  
  458.   return true;
  459. }
  460.  
  461. bool TLine::GetPenColor()
  462. {
  463.   TChooseColorDialog::TData colors;
  464.   static TColor custColors[16] =
  465.   {
  466.     0x010101L, 0x101010L, 0x202020L, 0x303030L,
  467.     0x404040L, 0x505050L, 0x606060L, 0x707070L,
  468.     0x808080L, 0x909090L, 0xA0A0A0L, 0xB0B0B0L,
  469.     0xC0C0C0L, 0xD0D0D0L, 0xE0E0E0L, 0xF0F0F0L
  470.   };
  471.  
  472.   colors.Flags = CC_RGBINIT;
  473.   colors.Color = TColor(QueryColor());
  474.   colors.CustColors = custColors;
  475.   if (TChooseColorDialog(0, colors).Execute() != IDOK)
  476.     return false;
  477.   SetPen(colors.Color);
  478.   return true;
  479. }
  480.  
  481.  
  482. DEFINE_RESPONSE_TABLE1(TDrawView, TOleView)
  483.   EV_WM_LBUTTONDOWN,
  484.   EV_WM_MOUSEMOVE,
  485.   EV_WM_LBUTTONUP,
  486.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  487.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  488.   EV_COMMAND(CM_EDITCLEAR, CmClear),
  489.   EV_COMMAND(CM_EDITUNDO, CmUndo),
  490.   EV_VN_COMMIT,
  491.   EV_VN_REVERT,
  492.   EV_VN_DRAWAPPEND,
  493.   EV_VN_DRAWDELETE,
  494.   EV_VN_DRAWMODIFY,
  495.   EV_WM_SETFOCUS,
  496. END_RESPONSE_TABLE;
  497.  
  498. TDrawView::TDrawView(TDrawDocument& doc, TWindow* parent)
  499. :
  500.   TOleView(doc, parent), DrawDoc(&doc)
  501. {
  502.   Line = new TLine(TColor::Black, 1);
  503.   Attr.AccelTable = IDA_DRAWVIEW;
  504.   SetViewMenu(new TMenuDescr(IDM_DRAWVIEW));
  505. }
  506.  
  507. void TDrawView::EvLButtonDown(uint modKeys, TPoint& point)
  508. {
  509.   TOleView::EvLButtonDown(modKeys, point);
  510.  
  511.   if (DragDC && !SelectEmbedded()) {
  512.     SetCapture();
  513.     Pen = new TPen(Line->QueryColor(), Line->QueryPenSize());
  514.     DragDC->SelectObject(*Pen);
  515.     DragDC->MoveTo(point);
  516.     Line->Add(point);
  517.   }
  518. }
  519.  
  520. void TDrawView::EvMouseMove(uint modKeys, TPoint& point)
  521. {
  522.   TOleView::EvMouseMove(modKeys, point);
  523.  
  524.   if (DragDC && !SelectEmbedded() && GetCapture() == *this) {
  525.     DragDC->LineTo(point);
  526.     Line->Add(point);
  527.   }
  528. }
  529.  
  530. void TDrawView::EvLButtonUp(uint modKeys, TPoint& point)
  531. {
  532.   if (DragDC) {
  533.     if (!SelectEmbedded()) {
  534.       ReleaseCapture();
  535.       if (Line->GetItemsInContainer() > 1)
  536.         DrawDoc->AddLine(*Line);
  537.       Line->Flush();
  538.       delete Pen;
  539.     }
  540.   }
  541.  
  542.   TOleView::EvLButtonUp(modKeys, point);
  543. }
  544.  
  545. void TDrawView::CmPenSize()
  546. {
  547.   Line->GetPenSize();
  548. }
  549.  
  550. void TDrawView::CmPenColor()
  551. {
  552.   Line->GetPenColor();
  553. }
  554.  
  555. void TDrawView::CmClear()
  556. {
  557.   DrawDoc->Clear();
  558. }
  559.  
  560. void TDrawView::CmUndo()
  561. {
  562.   DrawDoc->Undo();
  563. }
  564.  
  565. void TDrawView::Paint(TDC& dc, bool erase, TRect&rect)
  566. {
  567.   TOleView::Paint(dc, erase, rect);
  568.  
  569.   // Iterates through the array of line objects.
  570.   int j = 0;
  571.   TLine* line;
  572.   while ((line = const_cast<TLine *>(DrawDoc->GetLine(j++))) != 0)
  573.     line->Draw(dc);
  574. }
  575.  
  576. bool TDrawView::VnCommit(bool /*force*/)
  577. {
  578.   // nothing to do here, no data held in view
  579.   return true;
  580. }
  581.  
  582. bool TDrawView::VnRevert(bool /*clear*/)
  583. {
  584.   Invalidate();  // force full repaint
  585.   return true;
  586. }
  587.  
  588. bool TDrawView::VnAppend(uint index)
  589. {
  590.   TClientDC dc(*this);
  591.   const TLine* line = DrawDoc->GetLine(index);
  592.   line->Draw(dc);
  593.   return true;
  594. }
  595.  
  596. bool TDrawView::VnModify(uint /*index*/)
  597. {
  598.   Invalidate();  // force full repaint
  599.   return true;
  600. }
  601.  
  602. bool TDrawView::VnDelete(uint /*index*/)
  603. {
  604.   Invalidate();  // force full repaint
  605.   return true;
  606. }
  607.  
  608. DEFINE_RESPONSE_TABLE1(TDrawListView, TListBox)
  609.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  610.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  611.   EV_COMMAND(CM_EDITCLEAR, CmClear),
  612.   EV_COMMAND(CM_EDITUNDO, CmUndo),
  613.   EV_COMMAND(CM_EDITDELETE, CmDelete),
  614.   EV_VN_ISWINDOW,
  615.   EV_VN_COMMIT,
  616.   EV_VN_REVERT,
  617.   EV_VN_DRAWAPPEND,
  618.   EV_VN_DRAWDELETE,
  619.   EV_VN_DRAWMODIFY,
  620. END_RESPONSE_TABLE;
  621.  
  622. TDrawListView::TDrawListView(TDrawDocument& doc,TWindow *parent)
  623.        : TView(doc), TListBox(parent, GetNextViewId(), 0,0,0,0), DrawDoc(&doc)
  624. {
  625.   Attr.Style &= ~(WS_BORDER | LBS_SORT);
  626.   Attr.Style |= LBS_NOINTEGRALHEIGHT;
  627.   Attr.AccelTable = IDA_DRAWLISTVIEW;
  628.   SetViewMenu(new TMenuDescr(IDM_DRAWLISTVIEW));
  629. }
  630.  
  631. bool
  632. TDrawListView::CanClose()
  633. {
  634.   TView* curView = Doc->GetViewList();
  635.   while (curView) {
  636.     if (curView != this)
  637.       return true;
  638.  
  639.     curView = curView->GetNextView();
  640.   }
  641.  
  642.   return Doc->CanClose();
  643. }
  644.  
  645. bool TDrawListView::Create()
  646. {
  647.   TListBox::Create();
  648.   LoadData();
  649.   return true;
  650. }
  651.  
  652. void TDrawListView::LoadData()
  653. {
  654.   ClearList();
  655.   int i = 0;
  656.   const TLine* line;
  657.   while ((line = DrawDoc->GetLine(i)) != 0)
  658.     FormatData(line, i++);
  659.  
  660.   SetSelIndex(0);
  661. }
  662.  
  663. void TDrawListView::FormatData(const TLine* line, int unsigned index)
  664. {
  665.   char buf[80];
  666.   TColor color(line->QueryColor());
  667.   wsprintf(buf, "Color = R%d G%d B%d, Size = %d, Points = %d",
  668.            color.Red(), color.Green(), color.Blue(),
  669.            line->QueryPenSize(), line->GetItemsInContainer());
  670.   DeleteString(index);
  671.   InsertString(buf, index);
  672.   SetSelIndex(index);
  673. }
  674.  
  675. void TDrawListView::CmPenSize()
  676. {
  677.   int index = GetSelIndex();
  678.   const TLine* line = DrawDoc->GetLine(index);
  679.   if (line) {
  680.     TLine* newline = new TLine(*line);
  681.     if (newline->GetPenSize())
  682.       DrawDoc->ModifyLine(*newline, index);
  683.     delete newline;
  684.   }
  685. }
  686.  
  687. void TDrawListView::CmPenColor()
  688. {
  689.   int index = GetSelIndex();
  690.   const TLine* line = DrawDoc->GetLine(index);
  691.   if (line) {
  692.     TLine* newline = new TLine(*line);
  693.     if (newline->GetPenColor())
  694.       DrawDoc->ModifyLine(*newline, index);
  695.     delete newline;
  696.   }
  697. }
  698.  
  699. void TDrawListView::CmClear()
  700. {
  701.   DrawDoc->Clear();
  702. }
  703.  
  704. void TDrawListView::CmUndo()
  705. {
  706.   DrawDoc->Undo();
  707. }
  708.  
  709. void TDrawListView::CmDelete()
  710. {
  711.   DrawDoc->DeleteLine(GetSelIndex());
  712. }
  713.  
  714. bool TDrawListView::VnCommit(bool /*force*/)
  715. {
  716.   return true;
  717. }
  718.  
  719. bool TDrawListView::VnRevert(bool /*clear*/)
  720. {
  721.   LoadData();
  722.   return true;
  723. }
  724.  
  725. bool TDrawListView::VnAppend(uint index)
  726. {
  727.   const TLine* line = DrawDoc->GetLine(index);
  728.   FormatData(line, index);
  729.   SetSelIndex(index);
  730.   return true;
  731. }
  732.  
  733. bool TDrawListView::VnDelete(uint index)
  734. {
  735.   DeleteString(index);
  736.   HandleMessage(WM_KEYDOWN,VK_DOWN); // force selection
  737.   return true;
  738. }
  739.  
  740. bool TDrawListView::VnModify(uint index)
  741. {
  742.   const TLine* line = DrawDoc->GetLine(index);
  743.   FormatData(line, index);
  744.   return true;
  745. }
  746.  
  747. static char* PropNames[] = {
  748.   "Line Count",      // LineCount
  749.   "Description",       // Description
  750. };
  751.  
  752. static int PropFlags[] = {
  753.   pfGetBinary|pfGetText, // LineCount
  754.   pfGetText,             // Description
  755. };
  756.  
  757. const char*
  758. TDrawDocument::PropertyName(int index)
  759. {
  760.   if (index <= PrevProperty)
  761.     return TOleDocument::PropertyName(index);  // OC server change
  762.   else if (index < NextProperty)
  763.     return PropNames[index-PrevProperty-1];
  764.   else
  765.     return 0;
  766. }
  767.  
  768. int
  769. TDrawDocument::PropertyFlags(int index)
  770. {
  771.   if (index <= PrevProperty)
  772.     return TOleDocument::PropertyFlags(index); // OC server change
  773.   else if (index < NextProperty)
  774.     return PropFlags[index-PrevProperty-1];
  775.   else
  776.     return 0;
  777. }
  778.  
  779. int
  780. TDrawDocument::FindProperty(const char far* name)
  781. {
  782.   for (int i=0; i < NextProperty-PrevProperty-1; i++)
  783.     if (strcmp(PropNames[i], name) == 0)
  784.       return i+PrevProperty+1;
  785.   return 0;
  786. }
  787.  
  788. int
  789. TDrawDocument::GetProperty(int prop, void far* dest, int textlen)
  790. {
  791.   switch(prop)
  792.   {
  793.     case LineCount:
  794.     {
  795.       int count = Lines->GetItemsInContainer();
  796.       if (!textlen) {
  797.         *(int far*)dest = count;
  798.         return sizeof(int);
  799.       }
  800.       return wsprintf((char far*)dest, "%d", count);
  801.     }
  802.     case Description:
  803.       char* temp = new char[textlen]; // need local copy for medium model
  804.       int len = FileInfo.copy(temp, textlen);
  805.       strcpy((char far*)dest, temp);
  806.       return len;
  807.   }
  808.   return TOleDocument::GetProperty(prop, dest, textlen); // OC server change
  809. }
  810.